package ucd.csi.comp30220.fall2011.oteop.webapp.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import ucd.csi.comp30220.fall2011.oteop.flight.FlightStatus;
import ucd.csi.comp30220.fall2011.oteop.flight.FlightStatusSubscriber;
import ucd.csi.comp30220.fall2011.oteop.flight.FlightStatusListener;

import ucd.csi.comp30220.fall2011.oteop.webapp.client.Info;
import ucd.csi.comp30220.fall2011.oteop.webapp.client.ViewerService;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class ViewerServiceImpl extends RemoteServiceServlet implements ViewerService {

    private static final String[] images = new String[] { 
        "images/blueplane_t_n.png",
        "images/blueplane_t_nne.png", 
        "images/blueplane_t_ne.png",
        "images/blueplane_t_ene.png", 
        "images/blueplane_t_e.png",
        "images/blueplane_t_ese.png", 
        "images/blueplane_t_se.png",
        "images/blueplane_t_sse.png", 
        "images/blueplane_t_s.png",
        "images/blueplane_t_ssw.png", 
        "images/blueplane_t_sw.png",
        "images/blueplane_t_wsw.png", 
        "images/blueplane_t_w.png",
        "images/blueplane_t_wnw.png", 
        "images/blueplane_t_nw.png",
        "images/blueplane_t_nnw.png" 
    };
    
    private Map<String,Info> flights =  new HashMap<String,Info>();
    
    public ViewerServiceImpl() {
        System.err.println("############ New ViewerService #############");
        try {
            FlightStatusSubscriber subscriber = new FlightStatusSubscriber();
            subscriber.addListener(new FlightStatusListener() {
                public void onStatusUpdate(FlightStatus flight) {
                    //System.err.println(flight);
                    synchronized (flights) {
                        flights.put(flight.getNumber(), new Info(
                                flight.getNumber(), 
                                getImage(flight), 
                                getMessage(flight), 
                                flight.getPosition().getLatitude(),
                                flight.getPosition().getLongitude()));
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.err.println("Listening for status updates...");
    }
    
    private String getMessage(FlightStatus flight) {
        return "<div style=\"float:left; width:32px; bg:blue\">"
            + "<img src=\"images\\flags\\24\\UK.png\"></div>"
            + "<div style=\"float:left\"><b>" + flight.getNumber() +"</b>"
            + " (" +"???" +" &rarr; " +"???" +")<br>"
            + flight.getCourse() + " deg / " + flight.getSpeed() + " kts / "
            + flight.getAltitude() +" ft<br>Level Flight <i>On Time</i></div>";
    }
    
    private String getImage(FlightStatus flight) {
        double course = flight.getCourse();
        course = course < 0 ? 360+course : course;
        int index = (int) course/(360/images.length);
        return images[Math.min(index,images.length-1)];
    }
        
    public Info[] getAllFlightStatus() throws IllegalArgumentException {
        try {
            ArrayList<Info> list = new ArrayList<Info>();
            ArrayList<Info> delete = new ArrayList<Info>();
            synchronized (flights) {
                for (Info flight : flights.values()) {
                    if (flight.getTime() < System.currentTimeMillis() - 10*1000)
                        delete.add(flight);
                    else
                        list.add(flight);
                };
                for (Info flight : delete) {
                    flights.remove(flight.getId());
                }
            }
            return list.toArray(new Info[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Info[0];
    }
}
